package com.zb.config.mybatisplus;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * @ClassName CodeGenerator
 * @Description 代码生成器
 * @Author yso
 **/
public class CodeGenerator {

    /**
     * service 模块
     */
    public static final String SERVICE_MODULAR_NAME = "myplus.server";
    public static final String SERVICE_MODULAR_PATH = "com/zb/";

    /**
     * api 模块
     */
    public static final String API_MODULAR_NAME = "myplus.api";
    public static final String API_MODULAR_PATH = "com/zb/";
    /**
     * 基本路径
     */
    public static final String SRC_MAIN_JAVA = "/src/main/java/";

    /**
     * 资源路径
     */
    public static final String SRC_RESOURCE_JAVA = "/src/main/resources/";

    /**
     * 作者
     */
    public static final String AUTHOR = "xm";

    /**
     * 是否是 rest 接口
     */
    private static final boolean REST_CONTROLLER_STYLE = true;

    public static final String JDBC_MYSQL_URL = "jdbc:mysql://192.168.9.3:3306/ykk?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai";

    public static final String JDBC_DRIVER_NAME = "com.mysql.cj.jdbc.Driver";

    public static final String JDBC_USERNAME = "root";

    public static final String JDBC_PASSWORD = "123456789";

    public static void main(String[] args) {
        String tableName = scanner("表名");
        autoGenerator(tableName);
    }

    public static void autoGenerator(String tableName) {
        new AutoGenerator()
                .setGlobalConfig(getGlobalConfig())
                .setDataSource(getDataSourceConfig())
                .setPackageInfo(getPackageConfig())
                .setStrategy(getStrategyConfig(tableName))
                .setTemplateEngine(new VelocityTemplateEngine())
                .setTemplate(getTemplateConfig())
                .setCfg(getInjectionConfig())
                .execute();
    }

    private static StrategyConfig getStrategyConfig(String tableName) {
        return new StrategyConfig()
                .setNaming(NamingStrategy.underline_to_camel)
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setInclude(tableName)
                .setRestControllerStyle(REST_CONTROLLER_STYLE)
                .setEntityLombokModel(true)
                .setEntityBuilderModel(true)
                .setControllerMappingHyphenStyle(true);
    }

    private static PackageConfig getPackageConfig() {
        //获取项目目录
        String parentDir = System.getProperty("user.dir");
        String modelDir =
                parentDir + "/" + API_MODULAR_NAME + SRC_MAIN_JAVA + API_MODULAR_PATH + "entity";
        String mapperDir =
                parentDir + "/" + SERVICE_MODULAR_NAME + SRC_MAIN_JAVA + SERVICE_MODULAR_PATH + "mapper";
        String xmlDir = parentDir + "/" + SERVICE_MODULAR_NAME + SRC_RESOURCE_JAVA + "mapper";
        String controllerDir =
                parentDir + "/" + SERVICE_MODULAR_NAME + SRC_MAIN_JAVA + SERVICE_MODULAR_PATH
                        + "controller";
        String serviceDir =
                parentDir + "/" + SERVICE_MODULAR_NAME + SRC_MAIN_JAVA + SERVICE_MODULAR_PATH + "service";
        String serviceImplDir =
                parentDir + "/" + SERVICE_MODULAR_NAME + SRC_MAIN_JAVA + SERVICE_MODULAR_PATH
                        + "service/impl";
        //设置自定义输出目录（分布式项目使用）
        Map<String, String> pathInfo = new HashMap<>();
        pathInfo.put(ConstVal.ENTITY_PATH, modelDir);
        pathInfo.put(ConstVal.MAPPER_PATH, mapperDir);
        pathInfo.put(ConstVal.XML_PATH, xmlDir);
        pathInfo.put(ConstVal.SERVICE_PATH, serviceDir);
        pathInfo.put(ConstVal.SERVICE_IMPL_PATH, serviceImplDir);
        pathInfo.put(ConstVal.CONTROLLER_PATH, controllerDir);
        return new PackageConfig()
                .setPathInfo(pathInfo)
                .setParent("com.zb")
                .setService("service")
                .setServiceImpl("service.impl")
                .setController("controller")
                .setMapper("mapper")
                .setEntity("entity");
    }

    private static DataSourceConfig getDataSourceConfig() {
        return new DataSourceConfig()
                .setUrl(JDBC_MYSQL_URL)
                .setDriverName(JDBC_DRIVER_NAME)
                .setUsername(JDBC_USERNAME)
                .setPassword(JDBC_PASSWORD);
    }

    private static GlobalConfig getGlobalConfig() {
        return new GlobalConfig()
                .setDateType(DateType.ONLY_DATE)
                .setIdType(IdType.UUID)
                .setAuthor(AUTHOR)
                .setBaseColumnList(true)
                .setSwagger2(true)
                .setEnableCache(false)
                .setServiceName("%sService")
                .setEntityName("%sModel")
                .setFileOverride(true)
                .setBaseResultMap(true)
                .setOpen(false);
    }


    private static InjectionConfig getInjectionConfig() {
        return new InjectionConfig() {
            @Override
            public void initMap() {
                Map map = new HashMap();
                map.put("date", getDateTime());
                setMap(map);
            }
        };
    }

    private static String getDateTime() {
        LocalDateTime localDate = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
        return localDate.format(formatter);
    }

    private static TemplateConfig getTemplateConfig() {
        return new TemplateConfig()
                .setController("/template/controller.java.vm")
                .setService("/template/service.java.vm")
                .setServiceImpl("/template/serviceImpl.java.vm")
                .setEntity("/template/entity.java.vm")
                .setMapper("/template/mapper.java.vm")
                .setXml("/template/mapper.xml.vm");
    }

    private static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder sb = new StringBuilder();
        sb.append("please input " + tip + " : ");
        System.out.println(sb.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("please input the correct " + tip + ". ");
    }
}
